/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework
 * Version 2.10
 * 
 * Password Generator Class
 *      Provides static methods for generating passwords, and storing and comparing
 * one-way has versions of the password data.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.Security;
using System.Security.Cryptography;
using System.Data;
using System.Data.Sql;
using System.Web.Security;
using System.Text;

namespace Adaptive.Foundation.Data
{
    /// <summary>
    /// Provides static methods for generating passwords, and storing and comparing
    /// one-way has versions of the password data.
    /// </summary>
    public static class PasswordGenerator
    {
        /// <summary>
        /// Creates a new password value.
        /// </summary>
        /// <param name="maxLength">The maximum size of the password.</param>
        /// <returns>
        /// A new password string.
        /// </returns>
        public static string CreatePassword(int maxLength)
        {
            SqlMembershipProvider provider = null;      //Provider instance.
            string returnValue = null;                  //Return value.

            provider = new SqlMembershipProvider();
            returnValue = provider.GeneratePassword();

            //Ensure the correct length.
            if (returnValue.Length > maxLength)
                returnValue = returnValue.Substring(0, maxLength);

            provider = null;
            return returnValue;
        }
        /// <summary>
        /// Translates the raw password value into a one-way hash string 
        /// suitable for storage in the SQL Server database.
        /// </summary>
        /// <param name="original">
        /// The raw value to be hashed.
        /// </param>
        /// <returns>
        /// A hexadecimal-formatted string that represents the one-way hash of the original data.
        /// </returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString(System.String)")]
        public static string PrepareValueForStorage(string original)
        {
            SHA512Managed hash = null;                          //Hashing object.        
            byte[] data = null;                                 //Original data as byte array.
            byte[] storage = null;                              //Hash value.
            StringBuilder builder = null;                       //String concatenator.
            string returnValue = null;                          //Return value.

            //Translate the original to a byte array.
            data = Encoding.ASCII.GetBytes(original);

            //Compute the hash.
            hash = new SHA512Managed();
            storage = hash.ComputeHash(data);

            //Translate to a hexadecimal-formatted string.
            builder = new StringBuilder();
            for (int count = 0; count < storage.Length; count++)
                builder.Append(((int)storage[count]).ToString("X2"));

            returnValue = builder.ToString();

            //Clear and return.
            Array.Clear(storage, 0, storage.Length);
            Array.Clear(data, 0, data.Length);
            hash.Clear();
            hash = null;
            data = null;
            storage = null;

            return returnValue;
        }
    }
}
